package services;

import domain.entities.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
public class EthicsCommitteeCRUDService implements CRUDService<ComiteEtica>{

    private ComiteEticaDAO dao;
    private ContactPersonDAO contactPersondDAO;
    private CenterCRUDService centerCRUDService;

    public EthicsCommitteeCRUDService() {
    }

    @Autowired
    public EthicsCommitteeCRUDService(ComiteEticaDAO dao, ContactPersonDAO contactPersondDAO,
                                      CenterCRUDService centerCRUDService) {
        this.dao = dao;
        this.contactPersondDAO = contactPersondDAO;
        this.centerCRUDService = centerCRUDService;
    }

    @Override
    public <V extends Criteria> List<ComiteEtica> list(V criteria) {
        List<ComiteEtica> list = dao.findAll();
        if(criteria != null){
            Iterator<ComiteEtica> it = list.iterator();
            while(it.hasNext()){
                if(!criteria.isIn(it.next())){
                    it.remove();
                }
            }
        }
        return list;
    }

    public List<ComiteEtica> findAll(){
        return dao.findAll();
    }

    public ComiteEtica findById(int id) {
        return (ComiteEtica) dao.findById(id);
    }

    public void save(domain.entities.ComiteEtica comiteEtica) {
        _build(comiteEtica);

        ComiteEtica persisted = null;
        if(comiteEtica.getId() != null){
            persisted = dao.findById(comiteEtica.getId());
            for(ContactPerson cp : persisted.getContactPersons()){
                contactPersondDAO.delete(cp);
            }
        }
        ArrayList<ContactPerson> cps = new ArrayList<ContactPerson>(0);
        for(ContactPerson cp : comiteEtica.getContactPersons()){
            if(cp == null || cp.getRoleInCommittee() == null )
                cps.add(cp);
            else
                cp.setComiteEtica(comiteEtica);
        }

        comiteEtica.getContactPersons().removeAll(cps);
        dao.merge(comiteEtica);
    }

    private ComiteEtica _build(ComiteEtica comiteEtica) {
        Centro centro = null;
        if(comiteEtica.getCategory().equals(ComiteEtica.Category.Institutional)){
            centro = centerCRUDService.findById(comiteEtica.getSite().getId());
        }
        comiteEtica.setSite(centro);

        if(comiteEtica.getEcMeetingFrecuency() != null){
            if(!comiteEtica.getEcMeetingFrecuency().equals(ComiteEtica.ECMeetingFrecuency.Other)){
                comiteEtica.setOtherECMeetingFrecuency("");
            }
        }

        if(comiteEtica.getTimeToProvideDocumentApprovals() != null) {
            if(!comiteEtica.getTimeToProvideDocumentApprovals().equals(ComiteEtica.TimeToProvideDocuments.Other)){
                comiteEtica.setOtherTimeToProvideDocumentApprovals("");
            }
        }
        return comiteEtica;
    }

    public void merge(ComiteEtica comiteEtica) {
        dao.save((domain.entities.ComiteEtica) comiteEtica);
    }

    public void delete(ComiteEtica comiteEtica){
        dao.delete((domain.entities.ComiteEtica) comiteEtica);
    }
    public void deleteContactPersonById(int id) {
        ContactPerson person = contactPersondDAO.findById(id);
        if (person != null && person.getComiteEtica() != null){
            contactPersondDAO.delete(person);
        }
    }
    public List<ComiteEtica> findByName(String comiteEticaName) {
        Criteria cr = new CriteriaByName(comiteEticaName);
        return list(cr);
    }

    private class CriteriaByName extends Criteria{

        private String name;

        public CriteriaByName(String name) {
            this.name = name;
        }

        @Override
        public boolean isIn(Object element){
            boolean isIn = true;

            ComiteEtica other = (ComiteEtica) element;

            isIn = isSubstring(name, other.getName());
            return isIn;
        }
    }

//    public Set<ProtocoloCentro> getProtocolosCentro(ComiteEtica ce){
//        return dao.getProtocoloCentro(ce);
//    }

}
